<?php 
class PaymentDIBS
{
	public $MerchantId;
	public $MerchantUname;
	public $MerchantPass;
	
	public $Language;
	public $TestMode;
	public $CaptureNow;
	public $Amount;
	public $CurrencyCode;
	public $CurrencyNum;
	public $OrderId;
	public $Status;
	
	public $ComId;
	public $AcceptURL;
	public $CallbackURL;
	public $CancelURL;

	public $Transact;
	
	public function PaymentDIBS() 
	{ 
		$this->AcceptURL = SITE_URL.'plugins/payment/dibs_accept.php';
		$this->CallbackURL = SITE_URL.'plugins/payment/dibs_callback.php';
	    $this->CancelURL = SITE_URL.'plugins/payment/dibs_cancel.php';
		$this->ComId = 16;
		
		if(is_numeric($_REQUEST['transact']))
		{ $this->Transact = $_REQUEST['transact']; }
		self::loadConfig(); 
	}
	
	/* Get Methods */
	public function getMerchantId() { return $this->MerchantId; }
	public function getMerchantUname() { return $this->MerchantUname; }
	public function getMerchantPass() { return $this->MerchantPass; }
	
	public function getLanguage() { return $this->Language; }
	public function getTestMode() { return $this->TestMode; }
	public function getCaptureNow() { return intval($this->CaptureNow); }
	public function getAmount() { return $this->Amount; }
	public function getCurrencyCode() { return $this->CurrencyCode; }
	public function getCurrencyNum() { return $this->CurrencyNum; }
	public function getOrderId() { return $this->OrderId; }
	public function getTransact() { return $this->Transact; }
	/* Get Methods End */
	
	/* Set Methods */
	public function setMerchantId($val) { $this->MerchantId=$val; }
	public function setMerchantUname($val) { $this->MerchantUname=$val; }
	public function setMerchantPass($val) { $this->MerchantPass=$val; }
	
	public function setLanguage($val) { $this->Language=$val; }
	public function setTestMode($val) { $this->TestMode=$val; }
	public function setCaptureNow($val) { $this->CaptureNow=$val; }
	public function setAmount($val) { $this->Amount=$val; }
	public function setCurrencyCode($val) { $this->CurrencyCode=$val; }
	public function setCurrencyNum($val) { $this->CurrencyNum=$val; }
	public function setOrderId($val) { $this->OrderId=$val; }
	public function setTransact($val) { $this->Transact=$val; }
	/* Set Methods End */
	
	private function loadConfig()
	{
		$select  = 'SELECT site_id, param, value FROM '.DB_PERFIX.'shop_payment_config ';
		$select .= 'WHERE payment_id=2 AND (site_id='.SITE_ID.' OR site_id=0);';
		$result = mysql_query($select);
		if(mysql_num_rows($result) > 0)
		{
			while($row = mysql_fetch_array($result))
			{ $config[$row['site_id']][$row['param']] = $row['value']; }
			if($config[SITE_ID])
			{ $c = SITE_ID; }
			else
			{ $c = 0; }
			
			self::setMerchantId($config[$c]['merchant_id']);
			self::setTestMode($config[$c]['test_mode']);
			self::setCaptureNow($config[$c]['captureNow']);
			self::setCurrencyCode($config[$c]['currency_code']);
			self::setCurrencyNum($config[$c]['currency_num']);
			self::setLanguage($config[$c]['language']);
		}
	}
	
	public function validateOrder($order)
	{
		if($this->Transact)
		{
			$status = self::DIBSTransStat($order,$this->Transact);
			if($status == '2')
			{
				$order->setPaymentTransact($this->Transact);
				$order->setPaymentStatus(1);
				$order->updateOrder();
			}
			return $status;
		}
	}
	
	public function reauthorizeOrder($order)
	{
		if($order->getPaymentTransact() > 0)
		{
			$response = self::DIBSReAuth($order);
			return $response;
		}
	}
	
	public function captureOrder($order)
	{
		if($order->getPaymentTransact() > 0)
		{
			$response = self::DIBSCapt($order);
			return $response;
		}
	}
	
	function DIBSTransStat($order,$Transact) 
	{
		$out = '';
		//Set up post-variable string
		$postvars = "merchant=".self::parmchk($this->MerchantId);
		$postvars .= "&transact=".self::parmchk($Transact);
		$postvars .= "&orderid=".self::parmchk($order->getId());
		$postvars .= "&currency=".self::parmchk($this->CurrencyCode);
		$postvars .= "&amount=".self::parmchk(number_format(($order->getCostTotal(1)*100),0,'',''));
		
		$response = self::http_post('payment.architrade.com','/transstatus.pml',$postvars);
		
		//Deal with reponse
		if ( $response == "" ) //Response is an error
		{ $out = false; } 
		else //Response is good
		{ $out = trim($response); }
		
		return $out;
	}

	//!A function for asking DIBS for reauthorising a creditcard payment
	function DIBSReAuth($order) 
	{
		$response['statuscode'] = false;
		$response['error'] = '';
		
		//Set up post-variable string
		$postvars = "merchant=".self::parmchk($this->MerchantId);
		$postvars .= "&transact=".self::parmchk($order->getPaymentTransact());
		
		//Send post request
		$response = self::http_post('payment.architrade.com','/cgi-bin/reauth.cgi', $postvars);
		//Deal with reponse
		
		$responses = explode("&",$response);
		if(is_array($responses) && (count($responses) > 1))
		{
			foreach(array_keys($responses) as $key)
			{
				$params = explode('=', $responses[$key]);
				if(is_array($params))
				{
					if(($params[0] == 'status') && ($params[1] == 'ACCEPTED'))
					{ 
						$response['statuscode'] = true; 
						$response['statustxt'] = $params[1];
						$response['info'] = 'Reauthorisation accepted';
					}
					else
					{
						if($params[0] == 'reason')
						{
							$response['reason'] = $params[1];
							$response['reason_txt'] = self::getStatusString($params[1], 'reauth.cgi');
							$response['error'] = self::getStatusString($params[1], 'reauth.cgi');
							$response['info'] = self::getStatusString($params[1], 'reauth.cgi');
						}
						else
						{ $response[$params[0]] = $params[1]; }
					}
				}
			}
		}
	  	return $response;
	}

	//!A function for asking DIBS for capturing an already authorised creditcard payment
	function DIBSCapt($order) 
	{
		$response['statuscode'] = false;
		$response['error'] = '';
		
		//Set up post-variable string
		$postvars = "merchant=".self::parmchk(self::getMerchantId());
		$postvars .= "&orderid=".self::parmchk($order->getId());
		$postvars .= "&transact=".self::parmchk($order->getPaymentTransact());
		$postvars .= "&amount=".self::parmchk(number_format(($order->getCostTotal(1)*100),0,'',''));
		
		//Check if MD5key check is used and add if it is
		if ( count($MD5) == 2 ) {
		$md5Key = md5($MD5['K2'].md5($MD5['K1'].$postvars));
		$postvars .= "&md5key=".$md5Key;
		}
		
		$postvars .= "&textreply=yes";
		$postvars .= "&force=true";
		
		//Add testvar if "yes"
		if(self::getTestMode() > 0) 
		{ $postvars .= "&test=yes";  }
		
		//Send post request
		$response = self::http_post('payment.architrade.com','/cgi-bin/capture.cgi', $postvars);
		
		
		//Deal with reponse
		$responses = explode("&",$response);
		if(is_array($responses) && (count($responses) > 1))
		{
			foreach(array_keys($responses) as $key)
			{
				$params = explode('=', $responses[$key]);
				if(is_array($params))
				{
					if(($params[0] == 'result') && ($params[1] == '0'))
					{ 
						$response['statuscode'] = true; 
						$response['statustxt'] = $params[1];
						$response['info'] = 'Capture sucessfull';
					}
					else
					{
						if($params[0] == 'reason')
						{
							$response['reason'] = $params[1];
							$response['reason_txt'] = self::getStatusString($params[1], 'capture.cgi');
							$response['error'] = self::getStatusString($params[1], 'reauth.cgi');
							$response['info'] = self::getStatusString($params[1], 'reauth.cgi');
						}
						else
						{ $response[$params[0]] = $params[1]; }
					}
				}
			}
		}
		return $response;
	}
	
	function parmchk($in) 
	{ return str_replace("&","",$in); }

	public function prepareOrder($order)
	{
		if($order)
		{
			if($order->getId() > 0)
			{
				global $txt;
				$paymentform  = '';
				//$paymentform .= '<form id="payform" name="payform" method="post" action="'.SITE_URL.'plugins/payment/dibs.php">';
				if(self::getTestMode() > 0)
				{ $paymentform .= '<input type="hidden" name="test" value="1" />'; }
				if(self::getCaptureNow() > 0)
				{ $paymentform .= '<input type="hidden" name="captureNow" value="1" />'; }
				$paymentform .= '<input type="hidden" name="merchant" value="'.self::getMerchantId().'" />';
				$paymentform .= '<input type="hidden" name="orderId" value="'.$order->getId().'" />';
				//$paymentform .= '<input type="hidden" name="uniqueoid" value="'.$order->getId().'" />';
				$paymentform .= '<input type="hidden" name="language" value="'.self::getLanguage().'" />';
				$paymentform .= '<input type="hidden" name="amount" value="'.number_format(($order->getCostTotal(1)*100),0,'','').'" />';
				$paymentform .= '<input type="hidden" name="currency" value="'.self::getCurrencyCode().'" />';

				$paymentform .= '<input type="hidden" name="acceptReturnUrl" value="'.$this->AcceptURL.'" />';
				$paymentform .= '<input type="hidden" name="callbackUrl" value="'.$this->CallbackURL.'" />';
				$paymentform .= '<input type="hidden" name="cancelreturnurl" value="'.$this->CancelURL.'" />';
				
				$paymentform .= '<input type="hidden" name="billingFirstName" value="'.$txt->formatText($order->getDeliveryName()).'" />';
				$paymentform .= '<input type="hidden" name="billingLastName" value="'.$txt->formatText($order->getDeliveryLastName()).'" />';
				$paymentform .= '<input type="hidden" name="billingAddress" value="'.$txt->formatText($order->getDeliveryAddress()).'" />';
				$paymentform .= '<input type="hidden" name="billingAddress2" value="'.$txt->formatText($order->getDeliveryAddress2()).'" />';
				$paymentform .= '<input type="hidden" name="billingPostalCode" value="'.$order->getDeliveryZip(4).'" />';
				$paymentform .= '<input type="hidden" name="billingPostalPlace" value="'.$txt->formatText($order->getDeliveryCity()).'" />';
				
				//$paymentform .= '<input type="hidden" name="delivery7.Kommentar" value="'.$order->getDeliveryComment().'" />';
				//$paymentform .= '<input type="hidden" name="priceinfo1.shippingcosts" value="'.number_format(($order->getCostShipping()*100),0,'','').'" />';
				//$paymentform .= '<input type="hidden" name="priceinfo2.VAT" value="'.number_format(($order->getCostItemsVat()*100),0,'','').'" />';
				/*
				$paymentform .= '<input type="hidden" name="oiTypes" value="QUANTITY;UNITCODE;DESCRIPTION;AMOUNT;ITEMID;VATPERCENT" />';
				$paymentform .= '<input type="hidden" name="oiNames" value="Items;UnitCode;Description;Amount;ItemId;VatPercent" />';
				
				if($order->getOrderItems())
				{
					$row = 1;
					foreach($order->getOrderItems() as $item)
					{
						$paymentform .= '<input type="hidden" name="oiRow'.$row.'" value="';
						$paymentform .= $item->getCount().';';
						$paymentform .= 'stk;';
						$paymentform .= $item->getItemTitle().';';
						$paymentform .= number_format(($item->getSingleItemPrice(1)*100),0,'','').';';
						$paymentform .= $item->getItemIdentity().';';
						$paymentform .= (($item->getTaxValue()-1)*10000).'" />';
						$row++;
					}
				}
				*/
				//$paymentform .= '</form>';
				
				if(file_exists(ORDERS_PATH.'dibs_order_'.$order->getId().'.html'))
				{ unlink(ORDERS_PATH.'dibs_order_'.$order->getId().'.html'); }
				
				file_put_contents(ORDERS_PATH.'dibs_order_'.$order->getId().'.html', $paymentform);
				
				return 'dibs_order_'.$order->getId().'.html';
			}
		}
	}
	
	//!Function for sending a 'within-php' post-request and receive the response-body as a string
	function http_post($host, $path, $data, $auth="") 
	{
		$sock = fsockopen("ssl://".$host, 443, $errno, $errstr, 30);
		if (!$sock) die("$errstr ($errno)\n");  
		
		fwrite($sock, "POST ".$path." HTTP/1.0\r\n");
		fwrite($sock, "Host: ".$host."\r\n");
		fwrite($sock, "Content-type: application/x-www-form-urlencoded\r\n");
		fwrite($sock, "Content-length: " . strlen($data) . "\r\n");
		fwrite($sock, "User-Agent: PHP-DIBS (Kaka Consult) v1.0 \r\n"); 
		
		//If basic authentication is required (e.g. payinfo.cgi, changestatus.cgi and refund.cgi)
		if ( is_array($auth) ) 
		{ fwrite($sock, "Authorization: Basic ".base64_encode($auth['username'].":".$auth['password'])."\r\n"); }
		
		fwrite($sock, "Accept: */*\r\n");
		fwrite($sock, "\r\n");
		fwrite($sock, $data."\r\n");
		fwrite($sock, "\r\n");
		
		//Take out the header first  
		$headers = "";
		while ( $str = trim(fgets($sock, 4096)) ) 
		{ $headers .= "$str\n"; }
		 
		//Then collect the body and prepare for returning
		$body = "";
		while ( !feof($sock) ) 
		{ $body .= fgets($sock, 4096); }  
		fclose($sock);
		return $body;
	}
	
	function getStatusString($code, $file = '')
	{
		$out = '';
		$code = intval($code);
		if(($file == 'reauth.cgi') || ($file == 'reauth.cgi') || ($file == 'ticket_auth.cgi'))
		{
			if($code == 0)
			{ $out = 'Rejected by acquirer'; }
			if($code == 1)
			{ $out = 'Communication problems'; }
			if($code == 2)
			{ $out = 'Error in the parameters sent to the DIBS server. An additional parameter called "message" is returned, with a value that may help identifying the error.'; }
			if($code == 3)
			{ $out = 'Error at the acquirer.'; }
			if($code == 4)
			{ $out = 'Credit card expired.'; }
			if($code == 5)
			{ $out = 'Your shop does not support this credit card type, the credit card type could not be identified, or the credit card number was not modulus correct.'; }
			if($code == 6)
			{ $out = 'Instant capture failed.'; }
			if($code == 7)
			{ $out = 'The order number (orderid) is not unique.'; }
			if($code == 8)
			{ $out = 'There number of amount parameters does not correspond to the number given in the split parameter.'; }
			if($code == 9)
			{ $out = 'Control numbers (cvc) are missing.'; }
			if($code == 10)
			{ $out = 'The credit card does not comply with the credit card type.'; }
			if($code == 11)
			{ $out = 'Declined by DIBS Defender.'; }
			if($code == 20)
			{ $out = 'Cancelled by user at 3D Secure authentication step '; }
		}
		if(($file == 'capture.cgi') || ($file == 'refund.cgi') || ($file == 'cancel.cgi') || ($file == 'changestatus.cgi'))
		{
			if($code == 0)
			{ $out = 'Accepted'; }
			if($code == 1)
			{ $out = 'No response from acquirer.'; }
			if($code == 2)
			{ $out = 'Timeout'; }
			if($code == 3)
			{ $out = 'Credit card expired.'; }
			if($code == 4)
			{ $out = 'Rejected by acquirer.'; }
			if($code == 5)
			{ $out = 'Authorisation older than7 days.'; }
			if($code == 6)
			{ $out = 'Transaction status on the DIBS server does not allow capture.'; }
			if($code == 7)
			{ $out = 'Amount too high.'; }
			if($code == 8)
			{ $out = 'Error in the parameters sent to the DIBS server. An additional parameter called "message" is returned, with a value that may help identifying the error.'; }
			if($code == 9)
			{ $out = 'Order number (orderid) does not correspond to the authorisation order number.'; }
			if($code == 10)
			{ $out = 'Re-authorisation of the transaction was rejected.'; }
			if($code == 11)
			{ $out = 'Not able to communicate with the acquier.'; }
			if($code == 12)
			{ $out = 'Confirm request error'; }
			if($code == 14)
			{ $out = 'Capture is called for a transaction which is pending for batch - i.e. capture was already called'; }
			if($code == 15)
			{ $out = 'Capture was blocked by DIBS.'; }
		}
		return $out;
	}
}
?>